package com.dk.shared.utils;


import com.dk.common.distribute.DistObjectFactory;
import com.dk.common.distribute.cache.DistCache;
import com.dk.common.model.UserDTO;
import com.dk.common.utils.SpringUtil;
import com.dk.shared.autoconfigure.common.SharedProperties;
import com.dk.shared.defs.SharedDefs;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
public class UserAuditorHelper {


    private static final AtomicReference<Boolean> BEARER_TOKEN_AUTHENTICATION_EXISTED = new AtomicReference<>();
    /**
     * 当前线程的 token 信息
     */
    private static final ThreadLocal<String> CURRENT_TOKEN = new ThreadLocal<>();

    private static DistObjectFactory distObjectFactory;


    public static Optional<UserDTO> getCurrentUser() {
        if (distObjectFactory == null) {
            distObjectFactory = SpringUtil.getBean(DistObjectFactory.class);
        }

        return retrieveCurrentToken().map(token -> {
            DistCache<String, UserDTO> cache = distObjectFactory.getCache(SharedDefs.USER_INFO_KEY);
            return cache.get(token);
        });
    }

    public static Optional<String> retrieveCurrentToken() {
        if (distObjectFactory == null) {
            distObjectFactory = SpringUtil.getBean(DistObjectFactory.class);
        }
        // 1. 先从请求中获取 token，请求中的 token 是最真实的
        String token;
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (Objects.nonNull(requestAttributes)) {
            HttpServletRequest request = requestAttributes.getRequest();
            token = request.getHeader(SharedProperties.getTokenName());
            if (StringUtils.hasLength(token)) {
                return Optional.of(token);
            }
        }

        token = CURRENT_TOKEN.get();
        if (StringUtils.hasLength(token)) {
            return Optional.of(token);
        }
        return Optional.empty();
    }


    /**
     * 设置 token
     *
     * @param currentToken token
     */
    public static void setCurrentToken(String currentToken) {
        CURRENT_TOKEN.set(currentToken);
    }

    public static void removeCurrentToken() {
        CURRENT_TOKEN.remove();
    }

}
